package org.chipu.jnids.alert;

import java.util.ArrayList;
import java.util.Collection;
import javax.annotation.Nonnull;
import org.chipu.jnids.controller.DBLayer;
import org.chipu.jnids.display.Message;
import org.chipu.jnids.display.TextConsole;
import org.chipu.jnids.response.ResponseSystem;
import org.chipu.jnids.sancp.SnapShotCreator;
import org.chipu.jnids.sce.StateCorrelationEngine;

public final class SnortProcessor implements AlertProcessor<SnortEvent> {
	@Nonnull
	private final DBLayer dbController;
	@Nonnull
	private final SnapShotCreator ssc;
	private static final Collection<ResponseSystem> responseSystems = new ArrayList<ResponseSystem>();
	static {
		register(TextConsole.getInstance());
	}

	public static void register(ResponseSystem rs) {
		responseSystems.add(rs);
	}

	public SnortProcessor(@Nonnull DBLayer dbController, @Nonnull SnapShotCreator ssc) {
		if (dbController == null || ssc == null)
			throw new IllegalArgumentException("Null arguments: " + dbController + ", " + ssc);
		this.dbController = dbController;
		this.ssc = ssc;
	}

	@Override
	public void eventArrived(SnortEvent ev) {
		if (ev == null)
			return;
		try {
			StateCorrelationEngine.INSTANCE.associateSnapshot(ev, ssc.createSnapshot());
			if (StateCorrelationEngine.INSTANCE.isAlreadyProcessed(ev)) {
				TextConsole.getInstance().addMessage(ev, Message.Type.DUPLICATED);
				return;
			}
			if (StateCorrelationEngine.INSTANCE.shouldBeIgnored(ev)) {
				TextConsole.getInstance().addMessage(ev, Message.Type.IGNORED);
				return;
			}
			if (StateCorrelationEngine.INSTANCE.isNotHazard(ev)) {
				TextConsole.getInstance().addMessage(ev, Message.Type.NOT_RISK);
				// TODO store
				return;
			}
			byte anormal = StateCorrelationEngine.INSTANCE.getAnormalActivityLevel(ev);

			// TODOLATER see if it belongs to a alert group (and store the alert group)
			for(ResponseSystem rs : responseSystems)
				rs.eventReceived(ev, anormal);
			// TODO store the alert to create new profiles later
			dbController.addDetectedAlert(ev);
			// TODOLATER setup a honeypot or block the attack
		} finally {
			StateCorrelationEngine.INSTANCE.unassociateSnapshot(ev);
		}
	}
}